"""委托给子生成器的语法"""
"""
    允许生成器将其部分操作委托给另一个生成器。这允许包含的一段代码被分解出来并放置在另一个容器中，
此外，允许子生成器返回一个值，并且该值可用于委派生成器。yield from yield 尽管该表达式只要用于委派给
子生成器，但该表达式实际上允许委派给任意生成器。 yield from
    对于简单的迭代器，本质上只是以下形式的简化形式：yield from iterable 或者 for item in iterable:yield item
"""


def g(x):
    yield from range(x, 0, -1)
    yield from range(x)


def a(x):
    yield from range(x, 0, -1)
    for item in range(x):
        yield item

# print(list(g(5)))  # [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]
# print(list(a(5))) # [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]


"""但是与普通的循环不同， 他允许子生成器直接从调用范围接受发送和抛出的值，
并将最终值返回给外部的生成器： yield from"""


def accumulate():
    tally = 0
    while 1:
        next = yield
        if next is None:
            return tally
        tally += next


def gather_tallies(tallies):
    while 1:
        tally = yield from accumulate()
        tallies.append(tally)


# tallies = []
# acc = gather_tallies(tallies)
# print(acc)  # <generator object gather_tallies at 0x000001CD2E8DDAC8>
# print(next(acc))
# for i in range(4):
#     acc.send(i)
# print(next(acc))
# print(next(acc))
# print(next(acc))
# print(next(acc))
#
# acc.send(None)
# print(tallies)


"""
推动这一变化的主要原理是，即使将设计与send和throw方法一起使用的生成器， 
也可以将其轻松的拆分为多个生成器， 
就像单个大型函数可以拆分多个子函数一样。"""


def test1():
    one = 0
    while 1:
        next = yield
        return next


def test2(list1):
    while 1:
        a = yield from test1()
        list1.append(a)


# list1 = []
# a = test2(list1)
# # 启动生成器
# next(a)
# for i in range(4):
#     a.send(i)

# print(list1)



























